package com.youdoneed.user.searchword;

import com.querydsl.core.types.Projections;
import com.querydsl.sql.SQLQuery;
import com.querydsl.sql.SQLQueryFactory;
import com.youdoneed.base.application.AppException;
import com.youdoneed.base.common.GlobalIdWorker;
import com.youdoneed.base.pagination.Page;
import com.youdoneed.base.pagination.Paging;
import com.youdoneed.user.application.QueryHelper;
import com.youdoneed.user.model.SearchWord;
import com.youdoneed.user.query.QSearchWord;
import com.youdoneed.user.vo.SearchWordStatistics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;

/**
 * 搜索词服务实现类。
 *
 * @author Ewing
 * @date 2017.2.8
 */
@Service
@Transactional
public class SearchWordServiceImpl implements SearchWordService {
    private final Logger logger = LoggerFactory.getLogger(SearchWordServiceImpl.class);

    @Autowired
    private SQLQueryFactory queryFactory;

    private QSearchWord qSearchWord = QSearchWord.SearchWord;

    /**
     * 添加搜索词。
     */
    @Override
    public long addSearchWord(SearchWord searchWord) {
        if (searchWord == null || !StringUtils.hasText(searchWord.getWord())) {
            throw new AppException("SearchWord info is empty.");
        }
        searchWord.setSearchWordId(GlobalIdWorker.nextString());
        searchWord.setCreateTime(new Date());
        return queryFactory.insert(qSearchWord)
                .populate(searchWord)
                .execute();
    }

    /**
     * 分页获取全部搜索词。
     */
    @Override
    public Page<SearchWord> findSearchWords(Paging paging, Date startTime, Date endTime) {
        SQLQuery<SearchWord> query = queryFactory.selectFrom(qSearchWord);
        if (startTime != null) {
            query.where(qSearchWord.createTime.after(startTime));
        }
        if (endTime != null) {
            query.where(qSearchWord.createTime.before(endTime));
        }
        query.orderBy(qSearchWord.createTime.desc());
        return QueryHelper.queryPage(paging, query);
    }

    @Override
    public Page<SearchWordStatistics> searchWordStatistics(
            Paging paging, Integer minSearchTimes, Integer maxSearchTimes, Date startTime, Date endTime) {
        SQLQuery<SearchWordStatistics> query = queryFactory
                .select(Projections.bean(SearchWordStatistics.class,
                        qSearchWord.word, qSearchWord.count().as("searchTimes")))
                .from(qSearchWord);
        if (startTime != null) {
            query.where(qSearchWord.createTime.after(startTime));
        }
        if (endTime != null) {
            query.where(qSearchWord.createTime.before(endTime));
        }
        query.groupBy(qSearchWord.word);
        if (minSearchTimes != null) {
            query.having(qSearchWord.count().goe(minSearchTimes));
        }
        if (maxSearchTimes != null) {
            query.having(qSearchWord.count().loe(maxSearchTimes));
        }
        query.orderBy(qSearchWord.count().desc());
        return QueryHelper.queryPage(paging, query);
    }

}
